using System.Collections.Generic;
using Data;
using Framework.GamePool;
using Framework.Timer;
using Framework.UI;
using IcecreamView;
using MintAnimation;
using MintAnimation.Core;
using UnityEngine;
using UnityEngine.Serialization;

public class GameLightCube : GameCube
{

    protected List<GameLight> Lights = new List<GameLight>();

    public LightData LightData;

    private bool _isSelect;

    private CubeHud _cubeHud;

    public float hight = 0.3f;

    /// <summary>
    /// 目标角度
    /// </summary>
    private int _targetRotate;

    private MintAnimation_Position _mintAnimation;

    private MintAnimation_Rotation _animationRotation;

    private TimeHandler _rotateHandler;

    public void OnInit(Vector2Int point)
    {
        this.ReverData();
        this.Point     = point;
        this._isSelect = true;
        var tween = this.transform.MoveTo(GameManager.ToV3(this.Point, this.hight), 0.35f, MintEaseMethod.InOutSine);
        tween.OnComplete = () => { UIManager.Instance.EventManager.SendEvent(EventCode.SelectCube, this); };
        tween.Play();
    }

    private void ReverData()
    {
        this._mintAnimation                = this.transform.GetComponent<MintAnimation_Position>();
        this._animationRotation            = this.transform.GetComponent<MintAnimation_Rotation>();
        this._animationRotation.OnComplete = null;
        this._mintAnimation.OnComplete     = null;
        this.IsActive                      = false;
        this.isLight                       = false;
        this.transform.localEulerAngles    = Vector3.zero;
        this._targetRotate                 = (int) this.transform.localEulerAngles.y;
        this.CurVector                     = LightVector.U;
        this._isSelect                     = false;
        this._animationRotation.Pause();
        this._mintAnimation.Pause();
        this.SetRotateVector();
    }

    public void OnActive(bool isActive) { }

    #region Anim and NorMal

    public void SetRotateVector()
    {
        this._targetRotate              =  this._targetRotate % 360;
        this.transform.localEulerAngles =  Vector3.up * this._targetRotate;
        this._targetRotate              += this._targetRotate < 0 ? 360 : 0;

        if (this._targetRotate == 0)
            this.CurVector = LightVector.U;
        else if (this._targetRotate == 90)
            this.CurVector = LightVector.R;
        else if (this._targetRotate == 180)
            this.CurVector = LightVector.D;
        else
            this.CurVector = LightVector.L;
    }

    public void PlayActiveAnim(bool isActive)
    {
        if (isActive != this.IsActive)
        {
            this.IsActive = isActive;
            this._mintAnimation.Pause();
            if (isActive)
            {
                this._animationRotation.OnComplete = null;
                this._animationRotation.Pause();
                this._mintAnimation.OnComplete              = this.SetRotateVector;
                this._mintAnimation.GetOptions().IsReversal = true;
                this._mintAnimation.Play();
            }
            else
            {
                this._mintAnimation.OnComplete              = null;
                this._mintAnimation.GetOptions().IsReversal = false;
                this._mintAnimation.Play();
            }
        }
    }

    public void PlayRotationAnim(bool isRight)
    {
        this._targetRotate += (isRight ? 1 : -1) * 90;
        this._animationRotation.Pause();
        var data = (MintAnimationDataVector) this._animationRotation.GetOptions();
        if (isRight == false)
        {
            data.StartValue = this.transform.localEulerAngles + new Vector3(0, (this.transform.localEulerAngles.y == 0 ? 360 : 0), 0);
            data.EndValue   = Vector3.up * (this._targetRotate + ((this._targetRotate < 0) ? 360 : 0));
        }
        else
        {
            if (this._targetRotate <= 0)
            {
                this._targetRotate += 360;
            }

            data.StartValue = this.transform.localEulerAngles;
            data.EndValue   = Vector3.up * (this._targetRotate);
        }

        this._animationRotation.OnComplete = this.SetRotateVector;
        this._animationRotation.Play();
    }

    private void SelectCube(bool isS)
    {
        if (isS != this._isSelect)
        {
            this._isSelect = isS;
            //被选中时 暂停效果， 取消选中时 激活
            this.PlayActiveAnim(!this._isSelect);
        }

        if (isS)
        {
            if (!this._cubeHud)
            {
                this._cubeHud                         = GamePoolMgr.Instance.InstantiatePoolObject<CubeHud>("CubeHud", this.transform);
                this._cubeHud.transform.localPosition = Vector3.zero;
                this._cubeHud.Cube                    = this;
                UIManager.Instance.EventManager.SendEvent(EventCode.CheckLight);
            }
        }
        else
        {
            if (this._cubeHud)
            {
                this._cubeHud.Cube = null;
                this._cubeHud.Pool_Disable();
                this._cubeHud = null;
                UIManager.Instance.EventManager.SendEvent(EventCode.CheckLight);
            }
        }
    }

    protected override void OnSetPoint()
    {
        var data = (MintAnimationDataVector) this._mintAnimation.GetOptions();
        data.StartValue = GameManager.ToV3(this._point);
        data.EndValue   = GameManager.ToV3(this._point, this.hight);
    }

    public override void Pool_Disable()
    {
        UIManager.Instance.EventManager.UnBindEvent(EventCode.DestroyCube,  this.OnDestroyCube);
        UIManager.Instance.EventManager.UnBindEvent(EventCode.RotateCube,   this.OnRotateCube);
        UIManager.Instance.EventManager.UnBindEvent(EventCode.SelectCube,   this.OnSelectCube);
        UIManager.Instance.EventManager.UnBindEvent(EventCode.UnSelectCube, this.OnUnSelectCube);
        if (this._cubeHud)
        {
            this._cubeHud.Cube = null;
            this._cubeHud.Pool_Disable();
            this._cubeHud = null;
        }

        base.Pool_Disable();
    }

    public override void Pool_Enable()
    {
        base.Pool_Enable();
        this.ReverData();
        UIManager.Instance.EventManager.BindEvent(EventCode.DestroyCube,  this.OnDestroyCube);
        UIManager.Instance.EventManager.BindEvent(EventCode.RotateCube,   this.OnRotateCube);
        UIManager.Instance.EventManager.BindEvent(EventCode.SelectCube,   this.OnSelectCube);
        UIManager.Instance.EventManager.BindEvent(EventCode.UnSelectCube, this.OnUnSelectCube);
    }


    private void OnRotateCube(EventArg obj)
    {
        if (this._isSelect == false)
        {
            return;
        }

        bool isRight = obj.GetValue<bool>();
        this.PlayRotationAnim(isRight);
    }

    private void OnUnSelectCube(EventArg obj)
    {
        if (this._isSelect)
        {
            this.SelectCube(false);
        }
    }

    private void OnSelectCube(EventArg obj)
    {
        GameLightCube cube = obj.GetValue<GameLightCube>();
        this.SelectCube(cube == this);
    }

    private void OnDestroyCube(EventArg obj)
    {
        if (this._isSelect == false)
        {
            return;
        }

        GameManager.Instance.GameRoom.RemoveCube(this.Point);
        UIManager.Instance.EventManager.SendEvent(EventCode.RecoveryCube, this.CubeType);
        this.Pool_Disable();
    }

    #endregion

    private void AddLightLine(LightVector lightVector)
    {
        var localIndex = (int) lightVector + (int) this.CurVector - 1;
        if (localIndex > 8)
        {
            localIndex = localIndex % 9 + 1;
        }

        var localVector = (LightVector) localIndex;
        // Debug.Log($"{Point} {lightVector} => {localVector}");
        var point     = GameManager.Instance.GameRoom.ControlEndPoint(this.Point, localVector);
        var gameLight = GamePoolMgr.Instance.InstantiatePoolObject<GameLight>("GameLight", this.transform);
        gameLight.transform.localPosition = Vector3.zero;
        gameLight.UpdateLight(this.Point, point);
        this.Lights.Add(gameLight);
        if (GameManager.Instance.GameRoom.GridData.ContainsKey(point) && !GameManager.Instance.GameRoom.GridData[point].isLight)
        {
            this._oldCube.Add(GameManager.Instance.GameRoom.GridData[point]);
            GameManager.Instance.GameRoom.GridData[point].OnInLight(localVector);
        }
    }

    public override void OnInLight(LightVector lightVector)
    {
        if (this.isLight || this.LightData == null)
            return;
        var index = ((int) lightVector + 4);
        index = index - (int) CurVector + 1;
        if (index < 1)
        {
            index += 8;
        }

        if (index > 8)
        {
            index = index % 9 + 1;
        }

        Debug.Log($"from {lightVector}  => {Point}");
        lightVector = (LightVector) (index);
        var inOutData = this.LightData.GetLightInOut(lightVector);
        if (inOutData != null)
        {
            this.isLight = true;
            for (int i = 0; i < inOutData.OutLights.Count; i++)
            {
                this.AddLightLine(inOutData.OutLights[i]);
            }
        }
    }

    public override void OnCloseLight()
    {
        this.Lights.Clear();
        base.OnCloseLight();
    }

}